/**
 * @addtogroup FXDRM
 * @{
 */

/**
 * @file
 * @brief Providing certificate algorithms
 */

#ifndef _FX_CERT_H_
#define _FX_CERT_H_

#ifdef __cplusplus
extern "C" {
#endif
	
// FX_PKCS7 handler.
FX_DEFINEHANDLE(FX_PKCS7)
// FX_PKCS12 handler.
FX_DEFINEHANDLE(FX_PKCS12)
// FX_X509 handler.
FX_DEFINEHANDLE(FX_X509)
// FX_CERTLIST handler.
FX_DEFINEHANDLE(FX_CERTLIST)
// FX_CERTSTORE handler.
FX_DEFINEHANDLE(FX_CERTSTORE)
// FX_CERTCRL handler.
FX_DEFINEHANDLE(FX_CERTCRL)
// FX_OCSP_REQUEST handler.
FX_DEFINEHANDLE(FX_OCSP_REQUEST)
// FX_OCSP_RESPONSE handler.
FX_DEFINEHANDLE(FX_OCSP_RESPONSE)
// FX_OCSP_CERTID handler.
FX_DEFINEHANDLE(FX_OCSP_CERTID)

// Digest type
typedef enum _FX_DIGEST_TYPE
{
     FX_DIGEST_SHA1 = 0,
     FX_DIGEST_MD5,
} FX_DIGEST_TYPE;

/** 
 * @brief Parses a pkcs12 file by IFX_FileRead pattern.
 *
 * @param[in]	pCert			The pkcs12 file read pointer.
 * @param[out]	pkcs12			Obtain the PKCS12 object.
 * @return TRUE for success, <br>
 *		   FALSE if a failure occurs or if parameter <i>pCert</i> or <i>pkcs12</i> is a <b>NULL</b> pointer.
 * @note After using this object, which need to be freed by FXPKI_PKCS12_Release.
 */
FX_BOOL		FXPKI_ParsePKCS12FromFile(IFX_FileRead* pCert, FX_PKCS12* pkcs12);

/** 
 * @brief Parses a pkcs12 data stream.
 *
 * @param[in]	pData			The PKCS#12 data stream.
 * @param[in]	len				The stream's length.
 * @param[out]	pkcs12			Obtain the PKCS12 object.
 * @return TRUE for success, <br>
 *		   FALSE if a failure occurs or if parameter <i>pData</i> or <i>pkcs12</i> is a <b>NULL</b> pointer.
 * @note After useing this object, which need to be freed by FXPKI_PKCS12_Release().
 */
FX_BOOL		FXPKI_ParsePKCS12FromBuffer(FX_LPCBYTE pData, FX_INT32 len, FX_PKCS12* pkcs12);

/** 
 * @brief Free the pkcs12 object.
 *
 * @param[in]	p12				The PKCS#12 object ready to be free.
 */
void		FXPKI_PKCS12_Release(FX_PKCS12 p12);

/** 
 * @brief Parses the PKCS12 object and extracts relevant data (private key; private key length; public key cert; CA chain).
 *
 * @param[in]	cert			The pkcs12 data.
 * @param[in]	password		The password of the PKCS#12 data.
 * @param[out]	privKey			Get a stream of PKCS#8 structure encode, this PKCS#8 structure contains the private key information.
 *								<b>NOTE</b>: After using the data stream, which need be freed manually.
 * @param[out]	privLen			Get stream length.
 * @param[out]	x509			Get the public key cert object.
 *								<b>NOTE</b>: After useing this cert object, we need call FXPKI_X509_Release() to free it.
 * @param[out]	list			Get CA chain of the public key cert. It can be passed NULL when we needn't to get this list.
 *								<b>NOTE</b>: After useing the list, we need call FXPKI_CertList_Release() to free it.
 * @return TRUE if successful<br>
 *		   FALSE if an error occurred.<br>
 *		   FALSE if parameter <i>cert</i>, <i>password</i>, <i>privKey</i>, <i>privLen</i> or <i>x509</i> is a <b>NULL</b> pointer.
 */
FX_BOOL			FXPKI_PKCS12_GetData(FX_PKCS12 cert, const char* password, FX_LPBYTE* privKey, FX_INT32* privLen, FX_X509* x509, FX_CERTLIST* list);

/** 
 * @brief Free the x509 object.
 *
 * @param[in]	The x509 object ready to be free.
 */
void			FXPKI_X509_Release(FX_X509 x509);

/** 
 * @brief Free the cert chain.
 *
 * @param[in]	The cert chain ready to be free.
 */
void			FXPKI_CertList_Release(FX_CERTLIST list);

/** 
 * @brief Parses a pkcs7 file by IFX_FileRead pattern.
 *
 * @param[in]	pCert			The pkcs7 file pointer.
 * @param[out]	pkcs7			Obtain the PKCS7 object.
 * @return TRUE for success, <br>
 *		   FALSE if a failure occurs or if parameter <i>pCert</i> or <i>pkcs7</i> is a <b>NULL</b> pointer.
 * @note: After useing the object, we need call FXPKI_PKCS7_Release() to free it.
 */
FX_BOOL			FXPKI_ParsePKCS7FromFile(IFX_FileRead* pCert, FX_PKCS7* pkcs7);

/** 
 * @brief Parses a PKCS7 data.
 *
 * @param[in]	pData			The pkcs7 data stream.
 * @param[in]	len				The stream's length.
 * @param[out]	pkcs7			Obtain the PKCS7 object.
 * @return TRUE for success, <br>
 *		   FALSE if a failure occurs or if parameter <i>pData</i> or <i>pkcs7</i> is a <b>NULL</b> pointer.
 * @note: After useing the object, we need call FXPKI_PKCS7_Release() to free it.
 */
FX_BOOL			FXPKI_ParsePKCS7FromBuffer(FX_LPCBYTE pData, FX_DWORD len, FX_PKCS7* pkcs7);

/** 
 * @brief Free the pkcs7 structure.
 *
 * @param[in]	p7				The pkcs7 structure ready to be free.
 */
void			FXPKI_PKCS7_Release(FX_PKCS7 p7);

/** 
 * @brief Decrypt content from a PKCS#7 enveloped data.
 *
 * @param[in]	cert			The pkcs7 object containing the envelop.
 * @param[in]	privKey			A PKCS#8 encode stream, which contains the private key information of the recipient.
 * @param[in]	privLen			The stream length.
 * @param[in]	x509			The public key cert of the recipient.
 * @param[out]	msg				The decrypted content.
 * @param[out]	msgLen			Parameter <i>msg</i>'s length.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>cert</i>, <i>privKey</i>, <i>x509</i>, <i>msg</i> or <i>msgLen</i> is a <b>null</b> pointer, or the parameter <i>privLen</i> is a Non positive(privLen <= 0).
 * @note: When the 'msg' is not needed, we should call FX_Free() to free it.
 */
FX_BOOL			FXPKI_PKCS7_Decrypt(FX_PKCS7 cert, FX_LPCBYTE privKey, FX_INT32 privLen, FX_X509 x509, FX_LPBYTE* msg, FX_INT32* msgLen);

/** 
 * @brief Get count of the recipients contained by the PKCS#7 envelope.
 *
 * @param[in]	pkcs7			PKCS#7 object containing the envelope.
 * @param[out]	count			Count of the recipients in the envelope.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>pkcs7</i> or <i>count</i> is a <b>null</b> pointer
 */
FX_BOOL			FXPKI_PKCS7_CountRecipientCount(FX_PKCS7 pkcs7, FX_INT32* count);

/** 
 * @brief Get issuer and serial about the recipient of special index in a PKCS#7 envelope.
 *
 * @param[in]	pkcs7			Pkcs7 object containing the envelop.
 * @param[in]	index			Index of the recipient.
 * @param[out]	issuer			Pointer to a buffer that receives the issuer name about the recipient.
 *								<b>NOTE:</b> This pointer can be set NULL or can point to a large enough buffer to contain be received the issuer name content.
 * @param[out]	issuerLen		Size of the issuer name content.
 * @param[out]	serial			Pointer to a buffer that receives the serial about the recipient.
 *								<b>NOTE:</b> This pointer can be set NULL or can point to a large enough buffer to contain be received the serial content.
 * @param[out]	serialLen		Size of the serial content.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>pkcs7</i> is a <b>null</b> pointer, or the parameter <i>index</i> is a Non positive(privLen <= 0).
 * @note: Parameters <i>issuer</i> and <i>serial</i> need to be set <b>NULL</b> when we want to know sizes of the issuer and the serial in advance.
 */
FX_BOOL			FXPKI_PKCS7_GetRecipientIssuerAndSerial(FX_PKCS7 pkcs7, FX_INT32 index, FX_LPBYTE issuer, FX_INT32 *issuerLen, FX_LPBYTE serial, FX_INT32 *serialLen);

/** 
 * @brief Check if a X509 certificate match with issuer and serial.
 *
 * @param[in]	x509			X509 cert object.
 * @param[in]	issuer			Pointer to the issuer name buffer.
 * @param[in]	issuerLen		Size of the issuer name content.
 * @param[in]	serial			Pointer to the serial buffer.
 * @param[in]	serialLen		Size of the serial content.
 * @return TRUE if the X509 object match with the issuer and the serial.<br>
 *		   Otherwise return FALSE.<br>
 *		   FALSE if parameter <i>x509</i>, <i>issuer</i> or <i>serial</i> is a <b>null</b> pointer.
 */
FX_BOOL			FXPKI_X509_CompareIssuerAndSerial(FX_X509 x509, FX_LPBYTE issuer, FX_INT32 issuerLen, FX_LPBYTE serial, FX_INT32 serialLen);

#define FX_CERTFILETYPE_DER  0
#define FX_CERTFILETYPE_PEM  1

/** 
 * @brief Output X509 to file
 *
 * @param[in]	x509			The X509 object ready to output.
 * @param[in]	dwFileType		Format of X509 to output to file.
 * @param[in]	pSaveFile		The stream access interface.
 */
FX_BOOL			FXPKI_X509_Encode(FX_X509 x509, FX_DWORD dwFileType, IFX_FileWrite* pSaveFile);

/** 
 * @brief Check if the x509 content contains CRL path information.
 *
 * @param[in]	x509			The X509 object ready to check.
 */
FX_BOOL			FXPKI_X509_HasCRLPath(FX_X509 x509);
/** 
 * @brief Get CRL object path from the x509 object.
 *
 * @param[in]	x509			The X509 object ready to get object.
 * @param[out]	crlPath			The CRL path.
 * @param[out]	pathLen			Parameter <i>crlPath</i>'s length.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>x509</i>, <i>crlPath</i>, <i>pathLen</i> is a <b>null</b> pointer, or the parameter <i>pathLen<i>is a Non positive(privLen <= 0).
 */
FX_BOOL         FXPKI_X509_GetCRLPath(FX_X509 x509, FX_LPBYTE* crlPath, FX_INT32* pathLen);

/** 
 * @brief Parse CRL object from the stream.
 *
 * @param[in]	pFile			The stream access interface.
 * @param[out]	certCrl			The CRL object parse from file.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>pFile</i>, <i>certCrl<i> is a <b>null</b> pointer.
 * @note After useing this request handler, which need be freed by FXPKI_CertCRL_Release().
 */
FX_BOOL         FXPKI_ParseCertCRLFromFile(IFX_FileRead* pFile, FX_CERTCRL* certCrl);

/** 
 * @brief free the CRL Object.
 *
 * @param[in]	certCrl			The CRL Object ready to be free.
 */
void            FXPKI_CertCRL_Release(FX_CERTCRL certCrl);

/** 
 * @brief Create a FX_CERTSTORE object;
 *
 * @param[out]	store			Obtain the FX_CERTSTORE object.
 * @return TRUE for success.<br>
 *		   FALSE if a failure occurs or if parameter <i>store</i> is a <b>null</b> pointer.
 */
FX_BOOL         FXPKI_CertStore_Create(FX_CERTSTORE* store);

/** 
 * @brief Release a FX_CERTSTORE object;
 *
 * @param[in]	store			The FX_CERTSTORE object.
 */
void            FXPKI_CertStore_Release(FX_CERTSTORE store);

/** 
 * @brief Get a root cert from a certs list specified;
 *
 * @param[in]	list			The list.
 * @param[out]	x509			Obtain the root cert.
 * @return TRUE for success.<br>
 *		   FALSE if a failure occurs or if parameter <i>list</i> or <i> x509 </i> is a <b>NULL</b> pointer.
 */
FX_BOOL         FXPKI_CertList_GetRootCert(FX_X509 cert, FX_CERTLIST list, FX_X509* rootCert);

/** 
 * @brief Get a root cert from a certs list specified;
 *
 * @param[in]	list			The list.
 * @param[out]	x509			Obtain the root cert.
 * @return TRUE for success.<br>
 *		   FALSE if a failure occurs or if parameter <i>list</i> or <i> x509 </i> is a <b>NULL</b> pointer.
 */
FX_BOOL         FXPKI_CertStore_AddTrustCert(FX_CERTSTORE store, FX_X509 x509);

/** 
 * @brief Add a crl object into the store;
 *
 * @param[in]	store			The store.
 * @param[in]	certCrl			The crl object.
 * @return TRUE for success.<br>
 *		   FALSE if a failure occurs or if parameter <i>store</i> or <i> certCrl </i> is a <b>NULL</b> pointer.
 */
FX_BOOL         FXPKI_CertStore_AddCRL(FX_CERTSTORE store, FX_CERTCRL certCrl);

/** 
 * @brief Verify cert validity;
 *
 * @param[in]	store			A store object, it contains trust root cert(s) and crls.
 * @param[in]	x509			The cert which will be verified.
 * @param[in]	list			A list containing the certs which can be used to make up cert chain.
 * @return TRUE if valid.<br>
 *		   FALSE if a failure occurs or if parameter <i>store</i> or <i> certCrl </i> is a <b>NULL</b> pointer.
 */
FX_BOOL         FXPKI_CertStore_VerifyCert(FX_CERTSTORE store, FX_X509 x509, FX_CERTLIST list);

/** 
 * @brief Sign on the data.
 *
 * @param[in]	x509			The x509 cert to sign on the summary.
 * @param[in]	privKey			A private key stream.
 * @param[in]	privLen			The length of <i>privKey<i>.
 * @param[in]	pSignData		The data to be signed.
 * @param[in]	dataLen			The length of <i>pSignData<i>.
 * @param[out]	signValue		The data after signed.
 * @param[out]	signLen			The length of <i>signValue<i>.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>x509</i>, <i>privKey</i>, <i>pSignData</i>, <i>signValue<i>, <i>signLen<i> is a <b>null</b> pointer, or the parameter <i>privLen<i>, <i>dataLen<i> is a Non positive(privLen <= 0).
 */
FX_BOOL         FXPKI_CertSign(FX_X509 x509, FX_LPCBYTE privKey, FX_INT32 privLen, FX_LPCBYTE pSignData, FX_INT32 dataLen, FX_LPBYTE* signValue, FX_INT32* signLen);

/** 
 * @brief Verify the sign of data.
 *
 * @param[in]	x509			The x509 cert to verify the sign.
 * @param[in]	pSignData		The data to be signed.
 * @param[in]	dataLen			The length of <i>pSignData<i>.
 * @param[in]	signValue		The data after signed.
 * @param[in]	signLen			The length of <i>signValue<i>.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>x509</i>, <i>privKey</i>, <i>pSignData</i> is a <b>null</b> pointer, or the parameter <i>privLen<i>, <i>dataLen<i> is a Non positive(privLen <= 0).
 */
FX_BOOL         FXPKI_CertVerifySign(FX_X509 x509, FX_LPCBYTE pSignData, FX_INT32 dataLen, FX_LPCBYTE signValue, FX_INT32 signLen);

/** 
 * @brief Parse X509 object from the stream.
 *
 * @param[in]	pFile			The stream access interface.
 * @param[out]	certCrl			The X%09 object parse from file.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>pFile</i> is a <b>null</b> pointer.
 * @note After useing this request handler, which need be freed by FXPKI_X509_Release().
 */
FX_BOOL         FXPKI_ParseX509FromFile(IFX_FileRead* pFile, FX_X509* x509);

/** 
 * @brief Parses a PKCS7 data.
 *
 * @param[in]	pData			The x509 data buffer.
 * @param[in]	len				The buffer's length.
 * @param[out]	x509			To get the X509 object.
 * @return TRUE for success, <br>
 *		   FALSE if a failure occurs or if parameter <i>pData</i> or <i>x509</i> is a <b>NULL</b> pointer.
 * @note: After useing the object, we need call FXPKI_X509_Release() to free it.
 */
FX_BOOL			FXPKI_ParseX509FromBuffer(FX_LPCBYTE pData, FX_DWORD len, FX_X509* x509);

/** 
 * @brief Create a ocsp request handler;
 *
 * @param[in]	cert			the certificate whose revocation status you want to check.
 * @param[in]	issuer			Pointer to the certificate that issued the certificate whose revocation status you want to check. This should be a trusted root certificate.
 * @param[out]	request			The ocsp request handler.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>cert</i>, <i>issuer</i>, <i>request<i> is a <b>null</b> pointer.
 * @note After useing this request handler, which need be freed by FXPKI_OCSP_RequestRelease().
 */
FX_BOOL         FXPKI_OCSP_RequestCreate(FX_X509 cert, FX_X509 issuer, FX_OCSP_REQUEST* request);

/** 
 * @brief free the ocsp request handler.
 *
 * @param[in]	request			The ocsp request handler ready to be free.
 */
void            FXPKI_OCSP_RequestRelease(FX_OCSP_REQUEST request);

/** 
 * @brief Set seed bit of a ocsp request handler.
 *
 * @param[in]	request			The ocsp request handler to set seed bit.
 * @param[in]	nBits			The seed bit to set, -1 for random.			.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>request</i> is a <b>null</b> pointer.
 */
FX_BOOL         FXPKI_OCSP_SetRequestSeedBit(FX_OCSP_REQUEST request, FX_INT32 nBits);

/** 
 * @brief Get seed bit of a ocsp request handler.
 *
 * @param[in]	request			The ocsp request handler to get seed bit.
 * @param[out]	value			The seed value.
 * @param[out]	len				Parameter <i>value</i>'s length.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>request</i>, <i>value<i>, <i>len<i> is a <b>null</b> pointer.
 */
FX_BOOL         FXPKI_OCSP_GetRequestSeedValue(FX_OCSP_REQUEST request, FX_LPBYTE* value, FX_INT32* len);

/** 
 * @brief Sign the ocsp request handler.
 *
 * @param[in]	request			The ocsp request handler to sign.
 * @param[in]	signerCert		The signer cert.
 * @param[in]	signerPrivkey	The private key stream.
 * @param[in]	signerPrivLen	The <i>signerPrivkey<i>'s length.
 * @param[in]	digestAlgo		Digest algorithm to apply to the data file. For details please see menu _FX_DIGEST_TYPE.
 * @return True for successful,<br>
 *		   FALSE for failure.
 *		   FALSE if parameter <i>request</i>, <i>signerCert</i>, <i>signerPrivKey</i> is a <b>null</b> pointer, or the parameter <i>signerPrivLen<i>is a Non positive(privLen <= 0).
*/
FX_BOOL         FXPKI_OCSP_SignRequest(FX_OCSP_REQUEST request, FX_X509 signerCert, FX_LPCBYTE signerPrivKey, FX_INT32 signerPrivLen ,FX_DIGEST_TYPE digestAlgo);

/** 
 * @brief Get content of the ocsp request handler.
 *
 * @param[in]	request			The ocsp request handler to get content.
 * @param[out]	data			The content data.
 * @param[out]	len				the length of <i>data<i>.
 * @return True for successful,<br>
 *		   FALSE for failure.
 *		   FALSE if parameter <i>request</i>, <i>data<i>, <i>len<i> is a <b>null</b> pointer.
*/
FX_BOOL         FXPKI_OCSP_GetRequestContent(FX_OCSP_REQUEST request, FX_LPBYTE* data, FX_INT32* len);

/** 
 * @brief Get certid of the ocsp request handler.
 *
 * @param[in]	request			The ocsp request handler to get content.
 * @param[out]	certID			The certID.
 * @return True for successful,<br>
 *		   FALSE for failure.
 *		   FALSE if parameter <i>request</i>, <i>certID<i> is a <b>null</b> pointer.
 *@note After useing this request handler, certID don't need to be released.
*/
FX_BOOL			FXPKI_OCSP_GetRequestCERTID(FX_OCSP_REQUEST request, FX_OCSP_CERTID* certID);
   
/** 
 * @brief Create a ocsp response handler;
 *
 * @param[in]	data			The reponse data.
 * @param[in]	len				The	length of <i>data<i> .
 * @param[out]	request			The ocsp request handler.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 * @note After useing this request handler, which need be freed by FXPKI_OCSP_ResponseRelease().
 */
FX_BOOL         FXPKI_OCSP_ResponseCreate(FX_LPCBYTE data, FX_INT32 len, FX_OCSP_RESPONSE* response);

/** 
 * @brief Free the ocsp response Object.
 *
 * @param[in]	response			The response handler ready to be free.
 */
void            FXPKI_OCSP_ResponseRelease(FX_OCSP_RESPONSE response);

/** 
 * @brief Get seed bit of a ocsp response handler.
 *
 * @param[in]	request			The ocsp response handler to get seed bit.
 * @param[out]	value			The seed value.
 * @param[out]	len				Parameter <i>value</i>'s length.
 * @return TRUE for success.<br>
 *		   FALSE for failure.<br>
 *		   FALSE if parameter <i>response</i>, <i>value<i>, <i>len<i> is a <b>null</b> pointer.
 */
FX_BOOL         FXPKI_OCSP_GetResponseSeedValue(FX_OCSP_RESPONSE response, FX_LPBYTE* value, FX_INT32* len);

// ocsp response status
typedef enum _FX_OCSP_STATUS
{
	FXOCSP_RESPONSE_STATUS_SUCCESSFUL = 0,
	FXOCSP_RESPONSE_STATUS_MALFORMEDREQUEST,
	FXOCSP_RESPONSE_STATUS_INTERNALERROR,
	FXOCSP_RESPONSE_STATUS_TRYLATER,    
	FXOCSP_RESPONSE_STATUS_SIGREQUIRED = 5, 
	FXOCSP_RESPONSE_STATUS_UNAUTHORIZED = 6,
} FX_OCSP_STATUS;

/** 
 * @brief Get status of the ocsp response handler.
 *
 * @param[in]	response		The ocsp response handler to get status.
 * @param[out]	status			The status of response, For details please see menu FX_OCSP_STATUS.
 * @return True for successful,<br>
 *		   FALSE for failure.
 *		   FALSE if parameter <i>response</i> is a <b>null</b> pointer.
*/
FX_BOOL         FXPKI_OCSP_GetResponseStatus(FX_OCSP_RESPONSE response, FX_OCSP_STATUS* status);

/** 
 * @brief Verify the ocsp response handler
 *
 * @param[in]	response		The ocsp response handler to verify.
 * @param[in]	store			The cert store to verify response handler.
 * @param[in]	deltaTime		the tolerance of time skew between client and server.
 * @param[in]	timeOut			The value of response timeout.
 * @param[in]	certID			The value of request certid;
 * @return True for successful,<br>
 *		   FALSE for failure.
 *		   FALSE if parameter <i>response</i>, <i>store</i> is a <b>null</b> pointer.
 * @note if the cert status is failed or known it return FALSE.
 * @note if the response checked in store failed it return FALSE.
 * @note if the update time of response checked failed it return FALSE.
*/
FX_BOOL         FXPKI_OCSP_ResponseVerify(FX_OCSP_RESPONSE response, FX_CERTSTORE store, FX_DWORD deltaTime, FX_DWORD timeOut, FX_OCSP_CERTID certID);

#ifdef __cplusplus
};
#endif

#endif	// _FX_CERT_H_

/** @} */
